/**********************************
 * @Description: MongoDB测试控制器
 * @Author: Ronnie Zhang
 * @LastEditor: Ronnie Zhang
 * @LastEditTime: 2023/12/07 20:30:00
 * @Email: zclzone@outlook.com
 * Copyright © 2023 Ronnie Zhang(大脸怪) | https://isme.top
 **********************************/

import { Controller, Get, Post, Body, Param, Query } from '@nestjs/common';
import { MongoService } from '@/shared/mongo.service';
import {
  ApiTags,
  ApiOperation,
  ApiResponse,
  ApiBody,
  ApiParam,
  ApiQuery,
} from '@nestjs/swagger';

@ApiTags('MongoDB')
@Controller('mongo')
export class MongoController {
  constructor(private readonly mongoService: MongoService) {}

  /**
   * 获取MongoDB连接状态
   */
  @Get('status')
  @ApiOperation({ summary: '获取MongoDB连接状态', description: '获取MongoDB数据库连接状态信息' })
  @ApiResponse({ status: 200, description: '连接状态信息' })
  async getConnectionStatus() {
    return {
      success: true,
      data: this.mongoService.getConnectionStatus(),
    };
  }

  /**
   * 检查MongoDB连接
   */
  @Get('health')
  async checkHealth() {
    const isConnected = await this.mongoService.isConnected();
    return {
      success: true,
      data: {
        connected: isConnected,
        status: isConnected ? 'healthy' : 'unhealthy',
      },
    };
  }

  /**
   * 获取数据库统计信息
   */
  @Get('stats')
  async getStats() {
    try {
      const stats = await this.mongoService.getStats();
      return {
        success: true,
        data: stats,
      };
    } catch (error) {
      return {
        success: false,
        message: '获取数据库统计信息失败',
        error: error.message,
      };
    }
  }

  /**
   * 获取所有集合
   */
  @Get('collections')
  @ApiOperation({ summary: '获取所有集合', description: '获取MongoDB数据库中的所有集合列表' })
  @ApiResponse({ status: 200, description: '集合列表' })
  @ApiResponse({ status: 500, description: '获取集合列表失败' })
  async getCollections(): Promise<any> {
    try {
      const collections = await this.mongoService.listCollections();
      return {
        success: true,
        data: collections,
      };
    } catch (error) {
      return {
        success: false,
        message: '获取集合列表失败',
        error: error.message,
      };
    }
  }

  /**
   * 创建集合
   */
  @Post('collections')
  async createCollection(@Body() body: { name: string; options?: any }): Promise<any> {
    try {
      const result = await this.mongoService.createCollection(body.name, body.options);
      return {
        success: true,
        data: result,
        message: `集合 ${body.name} 创建成功`,
      };
    } catch (error) {
      return {
        success: false,
        message: `创建集合 ${body.name} 失败`,
        error: error.message,
      };
    }
  }

  /**
   * 删除集合
   */
  @Post('collections/:name/delete')
  async deleteCollection(@Param('name') name: string): Promise<any> {
    try {
      await this.mongoService.dropCollection(name);
      return {
        success: true,
        message: `集合 ${name} 删除成功`,
      };
    } catch (error) {
      return {
        success: false,
        message: `删除集合 ${name} 失败`,
        error: error.message,
      };
    }
  }

  /**
   * 查询文档
   */
  @Get('collections/:name/documents')
  async findDocuments(
    @Param('name') name: string,
    @Query('query') query?: string,
    @Query('limit') limit?: string,
    @Query('skip') skip?: string,
  ): Promise<any> {
    try {
      const parsedQuery = query ? JSON.parse(query) : {};
      const options: any = {};
      if (limit) options.limit = parseInt(limit);
      if (skip) options.skip = parseInt(skip);

      const documents = await this.mongoService.find(name, parsedQuery, options);
      return {
        success: true,
        data: documents,
        count: documents.length,
      };
    } catch (error) {
      return {
        success: false,
        message: `查询集合 ${name} 文档失败`,
        error: error.message,
      };
    }
  }

  /**
   * 分页查询文档
   */
  @Get('collections/:name/documents/paginated')
  async findDocumentsPaginated(
    @Param('name') name: string,
    @Query('query') query?: string,
    @Query('page') page?: string,
    @Query('limit') limit?: string,
  ): Promise<any> {
    try {
      const parsedQuery = query ? JSON.parse(query) : {};
      const pageNum = page ? parseInt(page) : 1;
      const limitNum = limit ? parseInt(limit) : 10;

      const result = await this.mongoService.findWithPagination(
        name,
        parsedQuery,
        {},
        pageNum,
        limitNum,
      );
      return {
        success: true,
        data: result,
      };
    } catch (error) {
      return {
        success: false,
        message: `分页查询集合 ${name} 文档失败`,
        error: error.message,
      };
    }
  }

  /**
   * 插入文档
   */
  @Post('collections/:name/documents')
  async insertDocument(@Param('name') name: string, @Body() document: any): Promise<any> {
    try {
      const result = await this.mongoService.insertOne(name, document);
      return {
        success: true,
        data: result,
        message: '文档插入成功',
      };
    } catch (error) {
      return {
        success: false,
        message: `插入文档到集合 ${name} 失败`,
        error: error.message,
      };
    }
  }

  /**
   * 批量插入文档
   */
  @Post('collections/:name/documents/batch')
  async insertDocuments(@Param('name') name: string, @Body() body: { documents: any[] }): Promise<any> {
    try {
      const result = await this.mongoService.insertMany(name, body.documents);
      return {
        success: true,
        data: result,
        message: `成功插入 ${body.documents.length} 个文档`,
      };
    } catch (error) {
      return {
        success: false,
        message: `批量插入文档到集合 ${name} 失败`,
        error: error.message,
      };
    }
  }

  /**
   * 更新文档
   */
  @Post('collections/:name/documents/update')
  async updateDocument(
    @Param('name') name: string,
    @Body() body: { filter: any; update: any; options?: any },
  ): Promise<any> {
    try {
      const result = await this.mongoService.updateOne(name, body.filter, body.update, body.options);
      return {
        success: true,
        data: result,
        message: '文档更新成功',
      };
    } catch (error) {
      return {
        success: false,
        message: `更新集合 ${name} 文档失败`,
        error: error.message,
      };
    }
  }

  /**
   * 删除文档
   */
  @Post('collections/:name/documents/delete')
  async deleteDocument(@Param('name') name: string, @Body() body: { filter: any }): Promise<any> {
    try {
      const result = await this.mongoService.deleteOne(name, body.filter);
      return {
        success: true,
        data: result,
        message: '文档删除成功',
      };
    } catch (error) {
      return {
        success: false,
        message: `删除集合 ${name} 文档失败`,
        error: error.message,
      };
    }
  }

  /**
   * 计数文档
   */
  @Get('collections/:name/count')
  async countDocuments(@Param('name') name: string, @Query('query') query?: string): Promise<any> {
    try {
      const parsedQuery = query ? JSON.parse(query) : {};
      const count = await this.mongoService.countDocuments(name, parsedQuery);
      return {
        success: true,
        data: { count },
      };
    } catch (error) {
      return {
        success: false,
        message: `计数集合 ${name} 文档失败`,
        error: error.message,
      };
    }
  }

  /**
   * 创建索引
   */
  @Post('collections/:name/indexes')
  async createIndex(
    @Param('name') name: string,
    @Body() body: { indexSpec: any; options?: any },
  ): Promise<any> {
    try {
      const result = await this.mongoService.createIndex(name, body.indexSpec, body.options);
      return {
        success: true,
        data: result,
        message: '索引创建成功',
      };
    } catch (error) {
      return {
        success: false,
        message: `在集合 ${name} 创建索引失败`,
        error: error.message,
      };
    }
  }

  /**
   * 获取集合索引
   */
  @Get('collections/:name/indexes')
  async getIndexes(@Param('name') name: string): Promise<any> {
    try {
      const indexes = await this.mongoService.listIndexes(name);
      return {
        success: true,
        data: indexes,
      };
    } catch (error) {
      return {
        success: false,
        message: `获取集合 ${name} 索引失败`,
        error: error.message,
      };
    }
  }
}
